package io.renren.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import io.renren.common.exception.RRException;
import io.renren.common.utils.IntDexUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.validator.ValidatorUtils;
import io.renren.entity.*;
import io.renren.group.UpdateGroup;
import io.renren.param.NamePlateAliasParam;
import io.renren.param.RoomSaveParam;
import io.renren.param.SysDictQueryParam;
import io.renren.service.*;
import io.renren.vo.RoomEntityVo;
import io.renren.vo.RoomVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 会议室
 *
 * @author 1
 * @email 1@2.com
 * @date 2021-08-19 11:56:03
 */
@RestController
@RequestMapping("/room")
@Validated
@Slf4j
public class RoomController {

    @Autowired
    private RoomService roomService;
    @Autowired
    private EslWorkingService eslWorkingService;
    @Autowired
    private RoomEslService roomEslService;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private EslService eslService;
    @Autowired
    private SysDictService sysDictService;
    @Autowired
    private SeatEslService seatEslService;
    @Autowired
    private SeatService seatService;

    private String pageSize;

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params) {
        log.debug(params.toString());
//        if (StringUtils.isBlank((String) params.get("state"))) {
//            params.put("state", "usable");
//        }


        if ((String) params.get("bookDate") != null) {

            Date bookDate = Convert.toDate((String) params.get("bookDate"));
            if (DateUtil.between(bookDate, new Date(), DateUnit.DAY) > 7) {
                return R.error("只能预定7天以内的会议室");
            }
        }

        PageUtils page = roomService.queryPage(params);

        List<RoomVo> eslEntities = (List<RoomVo>) page.getList();
        for (RoomVo eslEntity : eslEntities) {
            for (Map<String, String> eslIdMap : eslEntity.getEslIds()) {
                String eslId = eslIdMap.get("eslId");
                eslIdMap.put("eslId", String.valueOf(IntDexUtils.HtoD(eslId)));
            }
        }

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{compId}/{id}")
    public R info(@PathVariable("compId") String compId, @PathVariable("id") Long id) {
        RoomEntity room = roomService.queryByCompIdAndId(compId, id);
        if (room == null) {
            return R.error("根据id查不到数据");
        }
        Map<String, String> timeMap = new HashMap<>();
        RoomVo roomVo = new RoomVo();
        RoomEntityVo roomEntityVo = new RoomEntityVo().convertFor(room);
        SysDictQueryParam param = new SysDictQueryParam();
        param.setName("floor");
        param.setCode(room.getFloor());
        param.setType(room.getCompId());
        SysDictEntity dictEntity = sysDictService.queryByNameCodeType(param);
        roomEntityVo.setFloorName(dictEntity != null ? dictEntity.getValue() : room.getFloor());
        param.setName("roomState");
        param.setCode(room.getState());
        dictEntity = sysDictService.queryByNameCode(param);
        roomEntityVo.setState(dictEntity != null ? dictEntity.getValue() : room.getState());
        roomVo.setRoomEntityVo(roomEntityVo);

        timeMap = applicationService.queryBookedTimeByRoomId(room.getId());
        roomVo.setHalfHourVo(timeMap);

        Map<String, Object> map = new HashMap<>();
        map.put("roomId", room.getId());
        map.put("limit", "1000");
        PageUtils roomEslPage = roomEslService.queryPage(map);
        List<RoomEslEntity> roomEslEntities = (List<RoomEslEntity>) roomEslPage.getList();
        List<String> aliases = new ArrayList<>();
        List<Map<String, String>> maps = new ArrayList<>();
        for (RoomEslEntity roomEslEntity : roomEslEntities) {
            Map<String, String> eslMap = new HashMap<>();
            eslMap.put("type", roomEslEntity.getType());
            eslMap.put("eslId", String.valueOf(IntDexUtils.HtoD(roomEslEntity.getEslId())));
            eslMap.put("alias", roomEslEntity.getAlias());
            maps.add(eslMap);
        }
        roomVo.setEslIds(maps);
        roomVo.setAliases(aliases);

        return R.ok().put("room", roomVo);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    @Transactional
    public R save(@RequestBody RoomSaveParam param) {
        log.info("RoomSaveParam = {}", param.toString());

        Map<String, Object> map = new HashMap<>();
        map.put("compId", param.getCorpId());
        map.put("name", param.getName());
        PageUtils pageUtils = roomService.queryPage(map);
        if (CollectionUtil.isNotEmpty(pageUtils.getList())) {
            log.info("公司{}已有同名会议室{}", param.getCorpId(), param.getName());
            throw new RRException("已有同名的会议室，会议室名称不能重复");
        }

        //查价签是否补绑定过
        RoomEslEntity RoomDoorEsl = roomEslService.queryByEslId(param.getDoorEslId());
        if (RoomDoorEsl != null) {
            RoomEntity roomEntity1 = roomService.getById(RoomDoorEsl.getRoomId());
            throw new RRException("已被会议室" + roomEntity1.getName() + "绑定");
        }


        for (NamePlateAliasParam namePlateAliasParam : param.getNamePlateAliasParams()) {

            RoomEslEntity roomEslEntity1 = roomEslService.queryByEslId(namePlateAliasParam.getEslId());
            if (roomEslEntity1 != null) {
                RoomEntity roomEntity1 = roomService.getById(roomEslEntity1.getRoomId());
                throw new RRException("已被会议室" + roomEntity1.getName() + "绑定");
            }
            SeatEslEntity seatEslEntity = seatEslService.queryByEslId(namePlateAliasParam.getEslId());
            if (seatEslEntity != null) {
                SeatEntity seaEntity = seatService.getById(seatEslEntity.getSeatId());
                throw new RRException("已被工位" + seaEntity.getName() + "绑定");
            }
        }

        RoomEntity room = RoomEntity.convertFor(param);

        //bind ap
        if (StringUtils.isNotBlank(param.getApMac())) {

            Boolean bindResult = eslWorkingService.bindAp(param.getCorpId(), room.getApMac());
            if (!bindResult) {
                log.info("绑定结果：{}", bindResult);
                return R.error("绑定基站失败，请联系管理员");
            }
        }

        roomService.save(room);

        //获取roomId
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name", room.getName());
        map1.put("compId", param.getCorpId());
        PageUtils page = roomService.queryPage(map1);
        List<RoomVo> roomVos = (List<RoomVo>) page.getList();
        Long roomId = roomVos.get(0).getRoomEntityVo().getId();

        //保存会议室价签
        List<RoomEslEntity> roomEslEntities = RoomEslEntity.convertFor(param, roomId);
        roomEslService.saveOrUpdateBatch(roomEslEntities);

        //更新价签所属用户
        List<String> eslIds = new ArrayList<>();
        eslIds.add(param.getDoorEslId());

        final List<NamePlateAliasParam> namePlateAliasList = param.getNamePlateAliasParams();

        if (namePlateAliasList.size() > 0 && namePlateAliasList.size() % 2 != 0) {
            throw new RRException("桌面铭牌必须为2的陪数");
        }

        if (CollectionUtil.isNotEmpty(namePlateAliasList)) {
            List<String> eslIdList = namePlateAliasList.stream().map(NamePlateAliasParam::getEslId).collect(Collectors.toList());
            eslIds.addAll(eslIdList);
        }

        List<String> biEslIds = new ArrayList<>();
        for (String eslId : eslIds) {
            biEslIds.add(IntDexUtils.DtoH(new BigInteger(eslId)));
        }
        Map<String, Object> eslQueryMap = new HashMap<>();
        eslQueryMap.put("eslIds", biEslIds);
        eslQueryMap.put("pageSize", 500);
        PageUtils eslPage = eslService.queryPage(eslQueryMap);
        List<EslEntity> eslEntities = (List<EslEntity>) eslPage.getList();
        if (CollectionUtil.isEmpty(eslEntities)) {
            throw new RRException("门牌或铭牌不存在，请确认序列号是否正确");
        }
        for (EslEntity eslEntity : eslEntities) {
            eslEntity.setUser(param.getCorpId());
        }
        eslService.saveOrUpdateBatch(eslEntities);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @Transactional
    public R update(@RequestBody RoomSaveParam param) {
        ValidatorUtils.validateEntity(param, UpdateGroup.class);
        final Long roomId = param.getId();
        final RoomEntity roomEntity = roomService.getById(roomId);

        final List<NamePlateAliasParam> namePlateAliasList = param.getNamePlateAliasParams();

        if (namePlateAliasList != null) {


            if (namePlateAliasList.size() > 0 && namePlateAliasList.size() % 2 != 0) {
                throw new RRException("桌面铭牌必须为2的陪数");
            }

            //查价签是否补绑定过
            for (NamePlateAliasParam namePlateAliasParam : param.getNamePlateAliasParams()) {
                RoomEslEntity roomEslEntity1 = roomEslService.queryByEslId(namePlateAliasParam.getEslId());
                if (roomEslEntity1 != null) {
                    RoomEntity roomEntity1 = roomService.getById(roomEslEntity1.getRoomId());
                    throw new RRException("已被会议室[" + roomEntity1.getName() + "]绑定");
                }
                SeatEslEntity seatEslEntity = seatEslService.queryByEslId(namePlateAliasParam.getEslId());
                if (seatEslEntity != null) {
                    SeatEntity seaEntity = seatService.getById(seatEslEntity.getSeatId());
                    throw new RRException("已被工位[" + seaEntity.getName() + "]绑定");
                }
            }
            //变更会议室价签
            List<RoomEslEntity> roomEslEntities = roomEslService.queryByRoomId(roomId);
            if (CollectionUtil.isNotEmpty(roomEslEntities)) {
                List<String> eslIds = new ArrayList<>();
                for (RoomEslEntity roomEslEntity : roomEslEntities) {

                    eslIds.add(roomEslEntity.getEslId());
                    Map<String, Object> eslQueryMap = new HashMap<>();
                    eslQueryMap.put("eslIds", eslIds);
                    eslQueryMap.put("pageSize", 500);
                    PageUtils eslPage = eslService.queryPage(eslQueryMap);

                    //清空价签所属公司
                    List<EslEntity> eslEntities = (List<EslEntity>) eslPage.getList();
                    for (EslEntity eslEntity : eslEntities) {
                        eslEntity.setUser("default");
                    }
                    eslService.saveOrUpdateBatch(eslEntities);

                    roomEslService.removeById(roomEslEntity.getId());
                }
            }
            roomEslEntities = RoomEslEntity.convertFor(param, roomId);
            roomEslService.saveOrUpdateBatch(roomEslEntities);

            //更新价签所属用户
            List<String> eslIds = new ArrayList<>();
            eslIds.add(param.getDoorEslId());

            if (CollectionUtil.isNotEmpty(namePlateAliasList)) {
                List<String> eslIdList = namePlateAliasList.stream().map(NamePlateAliasParam::getEslId).collect(Collectors.toList());
                eslIds.addAll(eslIdList);
            }

            List<String> biEslIds = new ArrayList<>();
            for (String eslId : eslIds) {
                biEslIds.add(IntDexUtils.DtoH(new BigInteger(eslId)));
            }
            Map<String, Object> eslQueryMap = new HashMap<>();
            eslQueryMap.put("eslIds", biEslIds);
            eslQueryMap.put("pageSize", 500);
            PageUtils eslPage = eslService.queryPage(eslQueryMap);
            List<EslEntity> eslEntities = (List<EslEntity>) eslPage.getList();
            if (CollectionUtil.isEmpty(eslEntities)) {
                throw new RRException("门牌或铭牌不存在，请确认序列号是否正确");
            }
            for (EslEntity eslEntity : eslEntities) {
                eslEntity.setUser(param.getCorpId());
            }
            eslService.saveOrUpdateBatch(eslEntities);
        }
        roomService.updateById(RoomSaveParam.convertFor(param));

        //bind ap
        if (StringUtils.isNotBlank(param.getApMac())) {

            final String newApMac = param.getApMac();
            final String oldApMac = roomEntity.getApMac();
            /* apMac changed */
            if (!StringUtils.equals(newApMac, oldApMac)) {
                eslWorkingService.unBindAp(roomEntity.getCompId(), oldApMac);
                Boolean bindResult = eslWorkingService.bindAp(roomEntity.getCompId(), newApMac);
                if (!bindResult) {
                    log.info("绑定结果：{}", bindResult);
                    return R.error("绑定基站失败，请联系管理员");
                }
            }

        }

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @Transactional
    public R delete(@RequestBody Long[] ids) {
        for (Long id : ids) {
            List<ApplicationEntity> applicationEntities = applicationService.queryUnfinish(id);
            if (CollectionUtil.isNotEmpty(applicationEntities)) {
                RoomEntity roomEntity = roomService.getById(id);
                return R.error("存在未结束的预定记录，不能被删除！");
            }

            RoomEntity roomEntity = roomService.getById(id);

            //todo 同一个AP会被绑定多次，要先检查是否所有关系都解绑了？
//            //unbind ap
//            if (roomEntity != null && StringUtils.isNotBlank(roomEntity.getApMac())) {
//                Boolean bindResult = eslWorkingService.unBindAp(roomEntity.getCompId(), roomEntity.getApMac());
//                if (!bindResult) {
//                    return R.error("解绑基站失败，请联系管理员");
//                }
//            }

            //删除会议室价签
            Map<String, Object> roomEslMap = new HashMap<>();
            roomEslMap.put("roomId", id);
            PageUtils pageUtils = roomEslService.queryPage(roomEslMap);
            List<RoomEslEntity> roomEslEntities = (List<RoomEslEntity>) pageUtils.getList();
            if (CollectionUtil.isNotEmpty(roomEslEntities)) {
                List<String> eslIds = new ArrayList<>();
                for (RoomEslEntity roomEslEntity : roomEslEntities) {

                    eslIds.add(roomEslEntity.getEslId());
                    Map<String, Object> eslQueryMap = new HashMap<>();
                    eslQueryMap.put("eslIds", eslIds);
                    eslQueryMap.put("pageSize", 500);
                    PageUtils eslPage = eslService.queryPage(eslQueryMap);

                    //清空价签所属公司
                    List<EslEntity> eslEntities = (List<EslEntity>) eslPage.getList();
                    for (EslEntity eslEntity : eslEntities) {
                        eslEntity.setUser("default");
                    }
                    eslService.saveOrUpdateBatch(eslEntities);

                    roomEslService.removeById(roomEslEntity.getId());
                }
            }


            roomService.removeByIds(Arrays.asList(ids));
        }
        return R.ok();
    }
}
